package org.activequant.data.util;

import java.util.Iterator;

import org.activequant.core.domainmodel.marketscanner.ScanDataEntity;
import org.activequant.core.types.TimeStamp;
import org.activequant.core.util.IteratorHelper;
import org.apache.log4j.Logger;

/**
 * Iterator wrapper that filters out all data that does not fit into the specified interval.<br/>
 * A ScanProtectTimeIntervalIterator&lt;T extends ScanDataEntity&lt;T&gt;&gt; extends IteratorHelper&lt;T&gt;. Holds the following associated variables:
 * <ul>
 * <li>iterator(Iterator&lt;T&gt;)</li>
 * <li>from(TimeStamp)</li>
 * <li>to(TimeStamp)</li>
 * </ul>
 * @param <T>
 */
public class ScanProtectTimeIntervalIterator<T extends ScanDataEntity<T>> extends IteratorHelper<T> {
	private static final Logger LOG = Logger.getLogger(ScanProtectTimeIntervalIterator.class);
	/**
	 * private final Iterator&lt;T&gt; iterator;
	 */
	private final Iterator<T> iterator;
	/**
	 * private final TimeStamp from;
	 */
	private final TimeStamp from;
	/**
	 * private final TimeStamp to;
	 */
	private final TimeStamp to;

	/**
	 * Constructs a ScanProtectTimeIntervalIterator&lt;T extends ScanDataEntity&lt;T&gt;&gt; extends IteratorHelper&lt;T&gt; using the given iterator(Iterator&lt;T&gt;),
	 * from(TimeStamp) and to(TimeStamp) to set its associated iterator(Iterator&lt;T&gt;), from(TimeStamp) and to(TimeStamp)
	 * @param iterator base iterator (data source)
	 * @param from lower time limit (inclusive)
	 * @param to upper time limit (inclusive)
	 */
	public ScanProtectTimeIntervalIterator(Iterator<T> iterator, TimeStamp from, TimeStamp to) {
		this.iterator = iterator;
		this.from = from;
		this.to = to;
		LOG.debug("<init>(): created protector for interval: " + from.getDate() + " -- " + to.getDate());
	}
	/**
	 * a fetchNext returns the next element only if its timeStamp is in the associated from-to(TimeStamp) interval. (if too early - goes to the next one; if too late - returns null)
	 */
	@Override
	protected T fetchNext() {
		while(iterator.hasNext()) {
			T next = iterator.next();
			TimeStamp timeStamp = next.getTimeStamp();
			
			if(from.compareTo(timeStamp) > 0) {
				if(LOG.isDebugEnabled()) {
					LOG.debug("fetchNext(): skipping too early sample: " + next);
				}
				continue;
			}
			
			if(to.compareTo(timeStamp) <= 0) {
				if(LOG.isDebugEnabled()) {
					LOG.debug("fetchNext(): skipping too late sample: " + next);
				}
				return null;
			}
			
			return next;
		}
		
		return null;
	}
}